package core

import (
	"database/sql"
	"fmt"
	"net"
	"path/filepath"
	"sync"
)

type DBCmd struct {
	err error
	DB  *Sqlite3
}

var (
	instance_dbcmd *DBCmd
	once_dbcmd     sync.Once
)

func GetDBCmd() *DBCmd {
	once_dbcmd.Do(func() {
		instance_dbcmd = NewDBCmd()
	})
	return instance_dbcmd
}
func NewDBCmd() *DBCmd {
	return &DBCmd{DB: NewSqlite3()}
}
func (d *DBCmd) SetDB(db *sql.DB) {
	d.DB.DB = db
}
func (d *DBCmd) OpenDB(DBName string) (bool, error) {
	appSupportDir, err := GetResourcesDir()
	if err != nil {
		return false, err
	}
	dbPath := filepath.Join(appSupportDir, DBName)
	result, err := d.DB.OpenSqlite3(dbPath)
	d.err = err
	return result, err
}

// 返回值，bool是否登陆成功，string为用户名称,当为false，string返回错误信息
func (d *DBCmd) ConfirmLogin(userid uint64, userpwd string) (bool, string) {
	if d.err != nil {
		return false, d.err.Error()
	}
	text := ""
	result := false
	sql := "SELECT name,password FROM users where id=" + fmt.Sprintf("%d", userid)
	rows, err1 := d.DB.QuerySQL(sql)
	if err1 == nil {
		defer rows.Close()
		if rows.Next() {
			//读到记录,
			var name, password string
			if err2 := rows.Scan(&name, &password); err2 == nil {
				if userpwd == password {
					//密码正确
					text = name
					result = true
				} else {
					result = false
					text = "client password error"
				}
			}
		} else {
			result = false
			text = "clientid not exist"
		}
	}
	return result, text
}
func (d *DBCmd) ReadAllTopicsInfoFromDB(tm *TopicManager) {
	if d.err != nil {
		fmt.Println("Open DB Error:" + d.err.Error())
		return
	}
	rows, err := d.DB.QuerySQL("Select id,name,qos,type,clients from Topics")
	if err != nil {
		return
	}
	defer rows.Close()
	for rows.Next() {
		var id uint64
		var name, clients string
		var qos, types uint8
		rows.Scan(&id, &name, &qos, &types, &clients)

		t := &TopicFromDB{ID: id, Name: name, Qos: qos, Type: types, Clients: make(map[net.Conn]*Client)}
		tm.Topics[name] = t
	}
}
func (d *DBCmd) ReadKeyValue(name string) string {
	if d.err != nil {
		fmt.Println("Open DB Error:" + d.err.Error())
		return ""
	}
	rows, err := d.DB.QuerySQL("Select value from KeyValue where Key='" + name + "'")
	if err != nil {
		fmt.Println("Read Record Error:" + err.Error())
		return ""
	}
	defer rows.Close()
	if rows.Next() {
		aes := ""
		if err = rows.Scan(&aes); err != nil {
			fmt.Println("Read Record Value Error:" + err.Error())
			return ""
		}
		return aes
	}
	return ""
}

func (d *DBCmd) ReadOneTopic(tm *TopicManager, name string) *TopicFromDB {
	if d.err != nil {
		fmt.Println("Open DB Error:" + d.err.Error())
		return nil
	}
	rows, err := d.DB.QuerySQL("Select id,name,qos,clients from Topics where name=" + name)
	if err != nil {
		fmt.Println("Read DB Record Error:" + err.Error())
		return nil
	}
	defer rows.Close()
	if rows.Next() {
		var id uint64
		var name, clients string
		var qos uint8
		rows.Scan(&id, &name, &qos, &clients)

		t := &TopicFromDB{ID: id, Name: name, Qos: qos, Clients: make(map[net.Conn]*Client)}
		tm.Topics[name] = t
		return t
	}
	return nil
}
